home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Personal Computer World 2009 February
/
PCWFEB09.iso
/
Software
/
Resources
/
Chat & Communication
/
Digsby build 37
/
digsby_setup.exe
/
lib
/
pyxmpp
/
streamtls.pyo
(
.txt
)
< prev
next >
Wrap
Python Compiled Bytecode
|
2008-10-13
|
9KB
|
311 lines
# Source Generated with Decompyle++
# File: in.pyo (Python 2.5)
__revision__ = '$Id: streamtls.py 667 2006-12-11 16:48:59Z jajcus $'
__docformat__ = 'restructuredtext en'
import socket
import sys
import errno
import logging
from pyxmpp.streambase import StreamBase, STREAM_NS
from pyxmpp.streambase import FatalStreamError, StreamEncryptionRequired
from pyxmpp.exceptions import TLSNegotiationFailed, TLSError, TLSNegotiatedButNotAvailableError
try:
import M2Crypto
if M2Crypto.version_info < (0, 16):
tls_available = 0
else:
from M2Crypto import SSL
from M2Crypto.SSL import SSLError
import M2Crypto.SSL.cb as M2Crypto
tls_available = 1
except ImportError:
tls_available = 0
if not tls_available:
class SSLError(Exception):
pass
TLS_NS = 'urn:ietf:params:xml:ns:xmpp-tls'
class TLSSettings:
def __init__(self, require = False, verify_peer = True, cert_file = None, key_file = None, cacert_file = None, verify_callback = None, ctx = None):
self.require = require
self.ctx = ctx
self.verify_peer = verify_peer
self.cert_file = cert_file
self.cacert_file = cacert_file
self.key_file = key_file
self.verify_callback = verify_callback
class StreamTLSMixIn:
tls_available = tls_available
def __init__(self, tls_settings = None):
self.tls_settings = tls_settings
self._StreamTLSMixIn__logger = logging.getLogger('pyxmpp.StreamTLSMixIn')
def _reset_tls(self):
self.tls = None
self.tls_requested = False
def _make_stream_tls_features(self, features):
if self.tls_settings and not (self.tls):
tls = features.newChild(None, 'starttls', None)
ns = tls.newNs(TLS_NS, None)
tls.setNs(ns)
if self.tls_settings.require:
tls.newChild(None, 'required', None)
return features
def _write_raw(self, data):
logging.getLogger('pyxmpp.Stream.out').debug('OUT: %r', data)
try:
if self.tls:
self.tls.setblocking(True)
self.socket.send(data)
if self.tls:
self.tls.setblocking(False)
except (IOError, OSError, socket.error):
e = None
raise FatalStreamError('IO Error: ' + str(e))
except SSLError:
e = None
raise TLSError('TLS Error: ' + str(e))
def _read_tls(self):
if self.eof:
return None
while self.socket:
try:
r = self.socket.read()
if r is None:
return None
except socket.error:
e = None
if e.args[0] != errno.EINTR:
raise
return None
self._feed_reader(r)
def _read(self):
self._StreamTLSMixIn__logger.debug('StreamTLSMixIn._read(), socket: %r', self.socket)
if self.tls:
self._read_tls()
else:
StreamBase._read(self)
def _process(self):
try:
StreamBase._process(self)
except SSLError:
e = None
self.close()
raise TLSError('TLS Error: ' + str(e))
def _process_node_tls(self, xmlnode):
ns_uri = xmlnode.ns().getContent()
if ns_uri == STREAM_NS:
return False
elif ns_uri == TLS_NS:
self._process_tls_node(xmlnode)
return True
if self.tls_settings and self.tls_settings.require and not (self.tls):
raise StreamEncryptionRequired, 'TLS encryption required and not started yet'
return False
def _handle_tls_features(self):
ctxt = self.doc_in.xpathNewContext()
ctxt.setContextNode(self.features)
ctxt.xpathRegisterNs('tls', TLS_NS)
try:
tls_n = ctxt.xpathEval('tls:starttls')
tls_required_n = ctxt.xpathEval('tls:starttls/tls:required')
finally:
ctxt.xpathFreeContext()
if not self.tls:
if tls_required_n and not (self.tls_settings):
raise FatalStreamError, 'StartTLS support disabled, but required by peer'
if self.tls_settings and self.tls_settings.require and not tls_n:
raise FatalStreamError, 'StartTLS required, but not supported by peer'
if self.tls_settings and tls_n:
self._StreamTLSMixIn__logger.debug('StartTLS negotiated')
if not self.tls_available:
raise TLSNegotiatedButNotAvailableError, 'StartTLS negotiated, but not available (M2Crypto >= 0.16 module required)'
if self.initiator:
self._request_tls()
else:
self._StreamTLSMixIn__logger.debug('StartTLS not negotiated')
def _request_tls(self):
self.tls_requested = 1
self.features = None
root = self.doc_out.getRootElement()
xmlnode = root.newChild(None, 'starttls', None)
ns = xmlnode.newNs(TLS_NS, None)
xmlnode.setNs(ns)
self._write_raw(xmlnode.serialize(encoding = 'UTF-8'))
xmlnode.unlinkNode()
xmlnode.freeNode()
def _process_tls_node(self, xmlnode):
if not (self.tls_settings) or not tls_available:
self._StreamTLSMixIn__logger.debug('Unexpected TLS node: %r' % xmlnode.serialize())
return False
if self.initiator:
if xmlnode.name == 'failure':
raise TLSNegotiationFailed, 'Peer failed to initialize TLS connection'
elif xmlnode.name != 'proceed' or not (self.tls_requested):
self._StreamTLSMixIn__logger.debug('Unexpected TLS node: %r' % xmlnode.serialize())
return False
try:
self.tls_requested = 0
self._make_tls_connection()
self.socket = self.tls
except SSLError:
e = None
self.tls = 0
raise TLSError('TLS Error: ' + str(e))
self._StreamTLSMixIn__logger.debug('Restarting XMPP stream')
self._restart_stream()
return True
else:
raise FatalStreamError, 'TLS not implemented for the receiving side yet'
def _make_tls_connection(self):
if not tls_available or not (self.tls_settings):
raise TLSError, 'TLS is not available'
self.state_change('tls connecting', self.peer)
self._StreamTLSMixIn__logger.debug('Creating TLS context')
if self.tls_settings.ctx:
ctx = self.tls_settings.ctx
else:
ctx = SSL.Context('tlsv1')
verify_callback = self.tls_settings.verify_callback
if not verify_callback:
verify_callback = self.tls_default_verify_callback
if self.tls_settings.verify_peer:
self._StreamTLSMixIn__logger.debug('verify_peer, verify_callback: %r', verify_callback)
ctx.set_verify(SSL.verify_peer, 10, verify_callback)
else:
ctx.set_verify(SSL.verify_none, 10)
if self.tls_settings.cert_file:
ctx.use_certificate_chain_file(self.tls_settings.cert_file)
if self.tls_settings.key_file:
ctx.use_PrivateKey_file(self.tls_settings.key_file)
else:
ctx.use_PrivateKey_file(self.tls_settings.cert_file)
ctx.check_private_key()
if self.tls_settings.cacert_file:
try:
ctx.load_verify_location(self.tls_settings.cacert_file)
except AttributeError:
ctx.load_verify_locations(self.tls_settings.cacert_file)
except:
None<EXCEPTION MATCH>AttributeError
None<EXCEPTION MATCH>AttributeError
self._StreamTLSMixIn__logger.debug('Creating TLS connection')
self.tls = SSL.Connection(ctx, self.socket)
self._StreamTLSMixIn__logger.debug('Setting up TLS connection')
self.tls.setup_ssl()
self._StreamTLSMixIn__logger.debug('Setting TLS connect state')
self.tls.set_connect_state()
self._StreamTLSMixIn__logger.debug('Starting TLS handshake')
self.tls.connect_ssl()
self.state_change('tls connected', self.peer)
self.tls.setblocking(0)
try:
raise Exception
except:
pass
def tls_is_certificate_valid(self, store_context):
depth = store_context.get_error_depth()
if depth > 0:
return True
cert = store_context.get_current_cert()
cn = cert.get_subject().CN
if str(cn) != self.peer.as_utf8():
return False
return True
def tls_default_verify_callback(self, ok, store_context):
try:
self._StreamTLSMixIn__logger.debug('tls_default_verify_callback(ok=%i, store=%r)' % (ok, store_context))
X509 = X509
m2 = m2
import M2Crypto
depth = store_context.get_error_depth()
cert = store_context.get_current_cert()
cn = cert.get_subject().CN
self._StreamTLSMixIn__logger.debug(' depth: %i cert CN: %r' % (depth, cn))
if ok and not tls_is_certificate_valid(store_context):
self._StreamTLSMixIn__logger.debug(u'Common name does not match peer name (%s != %s)' % (cn, self.peer.as_utf8))
return False
return ok
except:
self._StreamTLSMixIn__logger.exception('Exception caught')
raise
def get_tls_connection(self):
return self.tls